// i.r(t), i.d(t, { default: () => VideoRecorderModule })
import webmWriter from "webm-writer"
import { ResizeCanvasCommand } from "../command/canvas.command"
import { TourStartCommand } from "../command/tour.command"
import keyConst from "../constant/key.const"
import { NullGeneratorResult } from "../engine/EngineGenerators"
import EngineContext from "../EngineContext"
import { TourStoppedMessage } from "../message/tour.message"
import SymbolList from "../SymbolList"
import browserUtil from "../utils/browser.util"
import funcUtil from "../utils/func.util"
import Logger from "../utils/Logger"
import Module from "./Module"
import SettingsModule from "./SettingsModule"
import WebGLRendererModule from "./WebGLRendererModule"
class FrostMage {
  _dateNow: () => number
  _performanceNow: () => number
  nowOverride: number
  fps: any
  constructor() {
    this._dateNow = Date.now
    this._performanceNow = performance.now
    this.nowOverride = 0
  }
  slowTime(e) {
    this.fps = e
    this.nowOverride = Date.now()
    Date.now = () => this.nowOverride
    performance.now = () => this.nowOverride
  }
  tick() {
    this.nowOverride += 1000 / this.fps
  }
  resetTime() {
    Date.now = this._dateNow
    performance.now = this._performanceNow
  }
}
const p = new Logger("video-recorder")
var g = {
  0: "STOPPED",
  1: "RECORDING",
  STOPPED: 0,
  RECORDING: 1
}

export default class VideoRecorderModule extends Module {
  state: number
  frostMage: FrostMage
  settingsModule: SettingsModule
  webglRenderer: WebGLRendererModule
  engine: EngineContext
  encoder: any
  constructor() {
    super(...arguments), (this.name = "video-recorder-module"), (this.state = g.STOPPED), (this.frostMage = new FrostMage())
  }
  async init(e, t: EngineContext) {
    this.settingsModule = await t.getModule(SettingsModule)
    this.webglRenderer = await t.getModuleBySymbol(SymbolList.WEBGL_RENDERER)
    this.engine = t
  }
  async record(e, t, s) {
    if (this.state !== g.STOPPED) return void p.warn("Can't start recording... we're already recording!")
    p.info("Starting recording of tour. Now is a good time to get a coffee :)"), (this.state = g.RECORDING)
    this.encoder = new webmWriter.WebMWriter({ quality: 0.95, frameRate: s })
    this.frostMage.slowTime(s)
    await this.engine.commandBinder.issueCommand(
      new ResizeCanvasCommand({
        resizeDimensions: [
          { property: keyConst.width, setDimension: e, duration: 0 },
          { property: keyConst.height, setDimension: t, duration: 0 }
        ]
      })
    )
    await this.engine.commandBinder.issueCommand(new TourStartCommand())
    const r = this.engine.subscribe(TourStoppedMessage, () => {
      r.cancel()
      this.state === g.RECORDING && this.stop()
    })
    const a = this
    const l = a.webglRenderer.cwfRenderer.renderer.getContext().canvas
    this.engine.startGenerator(function* () {
      for (; a.state === g.RECORDING; ) a.encoder.addFrame(l), yield new NullGeneratorResult(), a.frostMage.tick(), yield new NullGeneratorResult()
    })
  }
  async stop() {
    if (this.state !== g.RECORDING) return void p.warn("Can't stop recording, we weren't recording at all")
    this.frostMage.resetTime()
    this.state = g.STOPPED
    await this.engine.commandBinder.issueCommand(new ResizeCanvasCommand(funcUtil.initResizeDimensions(0))), p.info("Encoding tour to video...")
    const e = await this.encoder.complete()
    p.info("Tour encoded! Prompting user to download."), browserUtil.clickDown(e, "tour.webm")
  }
}
